
#ifndef _DRUMAPP_H_
#define _DRUMAPP_H_

#include <vector>
#include <map>

// SDL library headers 
#include "SDL.h"
#include "SDL_opengl.h"

#include "BitmapFont.h"

#include "common.h"
#include "SDL_GLApp.h"
#include "ShapeGroup.h"
#include "Drumstick.h"
#include "Player.h"
#include "Shape.h"
#include "Room.h"
#include "Fan.h"
#include "Composition.h"

__BEGIN_NAMESPACE_DECL_

enum DrumPlaybackState {
    DRUM_PLAYBACK_STOPPED = 0x01,
    DRUM_PLAYBACK_PLAYING = 0x02,
    DRUM_PLAYBACK_PAUSED = 0x03
};

enum DrumstickPolicy {
    DRUMSTICK_POLICY_PREFER_RIGHT = 0x01,
    DRUMSTICK_POLICY_PREFER_LEFT = 0x02
};

class DrumApp : public SDL_GLApp
{
    public:
        /**
         * Default constructor and destructor
         */
        DrumApp();
        DrumApp(const char *title);
        virtual ~DrumApp();

        virtual void InitApp();

    protected:
        virtual void Display();
        virtual void Process();
        virtual void Resize (int width, int height);
        virtual void Keyboard (const SDLKey& key);
        virtual void MouseMotion (Uint8 state, Uint16 x, Uint16 y);

    private:
        void init();
        void InitScene();
        void DisplayHelp();
        void DisplayNotification();
        void Projection();
        void LFPrint(const char *format, ...);
        void ErrCheck(const char *where);
        void DrawAxes(double scale);
        void DrawScene(int light);
        void ApplyPolygonMode();
        void PrintMatrix();
        void PlayInstrument (const char *instr, int policy);
        bool LoadComposition(int compositionNum,const char *defaultComposition);
        bool AdvanceComposition();
        void Light(int light);
        void ShadowMap();
        void InitMap();
        void LoadConfiguration();

    private:
        // BitmapFont instance
        BitmapFont *font;

        // Global objects for the scene
        std::vector<Shape *> scene; 
        Drumstick leftDrumstick;
        Drumstick rightDrumstick;
        Player player;
        Room room;
        Fan fan;
        GLUquadric *sphere;
        Composition composition;

        std::map<std::string, DrumstickLocation> locationMap;

        // State variables
        double fov;          // field of view
        double aspect;       // aspect ratio
        double dim;          // dimension of world
        double light0_angle; // angle of rotation of light around y axis
        bool lightsOn;       // Draw scene with lighting?
        bool shadowsOn;      // Enable/Disable shadows
        bool spotlightOn;    // Enable/Disable spotlight
        bool lightRotateOn;  // Enable/Disable light rotation
        bool cameraRotateOn; // Enable/Disable camera rotation in mode 2
        bool extraObjectsOn; // Enable/Disable extra objects (guitar/mic)
        bool drawAxes;       // Draw x,y and z axes at the origin?
        bool displayHelp;    // Display the help screen?
        bool displayFlag;    // Display state variables?
        int fanSpeed;        // Fan speed (0/off,1,2,3)
        int mode;            // 0=Orthogonal, 1=Perspective, 
                             // 2=Perspective w/FPS camera
        int polygonMode;     // 0=Fill, 1=Line, 2=Point
        int th_x, th_y;      // angle of rotation around x & y axes 
        int ambient;         // ambient for light 0
        int diffuse;         // diffuse for light 0
        int specular;        // specular for light 0
        int shininess;       // shininess for light 0
        int spotlightCutoff; // cutoff angle when spotlightOn = true
        int cymbalDispList;  // Display list for cymbal
        int drumstickDispList;  // Display list for drumstick
        int bassdrum;        // Display list for drumstick
        int snare;
        int tom12;
        int tom13;
        int tom16;
        int boomCrash;
        int kickPedal;
        int mallet;
        int pedal;
        int hihat14;
        int hihatStand;
        int ride20;
        int rideStand;
        int microphone;
        int guitar;

        int playbackState;
        int compositionNum;
};

__END_NAMESPACE_DECL_

#endif
